package com.hancher.gamelife2.noisedetect;

/**
 * 描述 : 傅里叶带复数的数据 <br/>
 * 时间 : 2024/5/23 17:52 <br/>
 * 作者 : Hancher ytu_shaoweijie@163.com
 */
public class Complex {
    public double i;
    public double j;// 虚数

    /**
     * i是数据的实部，j是数据的虚部值。返回值是一个虚数值
     * @param i
     * @param j
     */
    public Complex(double i, double j) {
        this.i = i;
        this.j = j;
    }

    /**
     * 求模
     * @return
     */
    public double getMod() {
        return Math.sqrt(i * i + j * j);
    }

    public static Complex Add(Complex a, Complex b) {
        return new Complex(a.i + b.i, a.j + b.j);
    }

    public static Complex Subtract(Complex a, Complex b) {
        return new Complex(a.i - b.i, a.j - b.j);
    }

    /**
     * 向量乘法
     * @param a
     * @param b
     * @return
     */
    public static Complex Mul(Complex a, Complex b) {// 乘法
        return new Complex(a.i * b.i - a.j * b.j, a.i * b.j + a.j * b.i);
    }

    /**
     * k，N是傅里叶变换里的系数，返回值是两个复数值在欧拉公式计算后的结果，返回值类型也是复数类型
     * 欧拉公式，将e的指数变换为复数的形式。
     * @param k
     * @param N
     * @return
     */
    public static Complex GetW(int k, int N) {
        return new Complex(Math.cos(-2 * Math.PI * k / N), Math.sin(-2 * Math.PI * k / N));
    }

    /**
     * 傅里叶变换的蝶形计算公式
     * a是偶数序列（类型是复数），b是奇数数列（类型是复数），w是e的指数展开的复数（类型是复数），返回值是复数数组类型
     * @param a
     * @param b
     * @param w
     * @return
     */
    public static Complex[] butterfly(Complex a, Complex b, Complex w) {
        return new Complex[]{Add(a, Mul(w, b)), Subtract(a, Mul(w, b))};
    }

    /**
     * 向量集合取模
     * @param complex
     * @return
     */
    public static Double[] toModArray(Complex[] complex) {
        Double[] res = new Double[complex.length];
        for (int i = 0; i < complex.length; i++) {
            res[i] = complex[i].getMod();
        }
        return res;
    }

}
